package org.NooLab.itexx.app.controller;


import java.util.Observable;
import java.util.Observer;


import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.ITexxWindowIntf;
import org.NooLab.itexx.app.controller.analyzer.SerDocumentScoring;
import org.NooLab.itexx.app.controller.results.SearchEngineResultItem;
import org.NooLab.itexx.app.controller.results.SearchEngineResults;
import org.NooLab.itexx.stuctures.RequestHistory;
import org.NooLab.utilities.logging.PrintLog;
import org.jdesktop.application.SessionStorage;




public class SessionManager implements SessionManagerIntf{

	ITexxWindowIntf app;
	ITexxWindowCommons appCommons;
	
	SessionStorage storage;
	RequestHistory requestHistory;
	
	/** finally completed and ranked items, ready for being displayed */
	private SearchEngineResults globalSearchEngineResults;
	/** buffer list  */
	SearchEngineResults seCompletedResultsItemsBuffer;
	ScoredSerDocuments scoredSerDocuments;
	
	SearchEngineResultsImporter importer ; // == Observer !!! for PageLoader
	
	boolean serScoringIsRunning = false ;
	SerScoring serScoring; 
	boolean collScoringIsRunning = false ;
	CollScoring collScoring;
	
	PrintLog out = new PrintLog(2,true);
	private int statusFlag;
	protected String lastPackageGuidAnnounced;
	// ========================================================================
	public SessionManager(ITexxWindowIntf app) {
		// 
		this.app = app ;
		
		appCommons = app.getAppCommons();
		// out = appCommons.out ;
		out.setPrefix("[ITEXX-SMGR]");
		// the data
		requestHistory = new RequestHistory();
		
		setGlobalSearchEngineResults(new SearchEngineResults( appCommons ));
		seCompletedResultsItemsBuffer = new SearchEngineResults(appCommons) ;
	
		scoredSerDocuments = new ScoredSerDocuments(this);
		
		// the tools
		
		importer = new SearchEngineResultsImporter(this);  
		serScoring = new SerScoring(this) ;
		
		collScoring = new CollScoring(this) ;
		
		
		out.setPrefix("[iTexx-Gui]") ;
	}
	// ========================================================================
	
	public void close(){
		serScoringIsRunning = false;
		collScoringIsRunning = false ;
		
		scoredSerDocuments.close() ;
	}
	
	public RequestHistory getHistory() {
		// 
		return requestHistory;
	}

	public RequestHistory getRequestHistory() {
		return requestHistory;
	}

	public ScoredSerDocuments getScoredSerDocuments() {
		return scoredSerDocuments;
	}

	public void setRequestHistory(RequestHistory requestHistory) {
		this.requestHistory = requestHistory;
	}

	public ITexxWindowIntf getApp() {
		return app;
	}

	public SessionStorage getStorage() {
		return storage;
	}
	
	public void publishPreparedSearchEngineResults( SearchEngineResults seResults) {

		// Adding the new results to global list
		
		// sorting it
		
		// setting the update trigger for the GUI (hosed by commons)
	}

	
	/*
	 			// loading of pages and calculating the rank values is organized by Session manager !!! ??? 
			// determineRanking( searchEngineResults );
			
			// now storing to files, preparing the snips for the Found-page 
			// and adding the snips to the global list
			// this list will be worked on by the object FoundResultsGuiUpdater (running a queue digester for that list)
			// which updates the Found-page 
			if (r==0){
				// put the items to the global list
				// (which should be hosted by a database !!!
				// it contains all items for the current session
				// hence this list is part of the SessionManager
				SessionManager smgr = appCommons.getSessionManager() ;
				smgr.publishPreparedSearchEngineResults( searchEngineResults );
				
				FoundResultsGuiUpdater gup; // just for quick dev jumping
			}
	 
	 */
	
	public Observer getObserver(){
		return importer;
	}

	public void setGlobalSearchEngineResults(SearchEngineResults globalSearchEngineResults) {
		this.globalSearchEngineResults = globalSearchEngineResults;
	}

	public SearchEngineResults getGlobalSearchEngineResults() {
		return globalSearchEngineResults;
	}

	public void setStateOnProcess(int typeOfPackage, String guid, int statusFlag) {
		// 
		
		this.statusFlag = statusFlag;
		
		if (statusFlag == SessionManagerIntf._REQUEST_RAID_COMPLETED){
			appCommons.getWindowGui().getMainStatusBar().showBusyIndicator(false);
		}
		
	}

	public void announceLastPackageguid(String guid) {
		// TODO Auto-generated method stub
		lastPackageGuidAnnounced = guid;
	}
	
}




/**
 * calc of rank score of documents based on all documents of a (series of ) request, 
 * modifies the global list
 * 
 * it needs a global result list of at least 50 documents
 *
 */
class CollScoring implements Runnable {
	
	SessionManager parent;
	
	public  CollScoring(SessionManager smgr){
		
		parent = smgr;
		
	}

	@Override
	public void run() {
		// 
		parent.collScoringIsRunning = true;
		
		
		parent.collScoringIsRunning = false ;
	}
	
	
	
} //  CollScoring 

// calc of rank score of single documents, put it to global list
class SerScoring implements Runnable {

	Thread serscThrd ;
	SessionManager parent;
	
	// ..........................................
	public SerScoring (SessionManager smgr){
		
		parent = smgr;

		serscThrd = new Thread(this,"serscThrd") ;
		serscThrd.start();
	}
	// ..........................................
	
	
	@Override
	public void run() {
		boolean isWorking = false;
		parent.serScoringIsRunning = true; 
		
		while (parent.serScoringIsRunning){
			
			if ((isWorking==false) && (parent.seCompletedResultsItemsBuffer.size()>0)){
				isWorking = true;
				
				SearchEngineResultItem serItem = parent.seCompletedResultsItemsBuffer.get(0) ;
				parent.seCompletedResultsItemsBuffer.getItems().remove(0) ;
				
				
								parent.out.print(2,"...going to score the document <"+serItem.getGuid()+"> retrieved through query " +serItem.getSeQuery());
				SerDocumentScoring scoring = new SerDocumentScoring(parent.appCommons, parent,serItem);
				parent.out.delay(300);
				
				if (parent.appCommons.getModelController().isUserBreak()){
					parent.seCompletedResultsItemsBuffer.getItems().clear();	
				}
				isWorking = false;
			}else{
				if (parent.out!=null){
					parent.out.delay(50);
				}
			}
			
		}// ->
		
		parent.serScoringIsRunning = false;
	}
	
	
}



// updated by PageLoader
class SearchEngineResultsImporter implements Observer{

	SessionManager parent;
	
	public SearchEngineResultsImporter(SessionManager smgr){
		parent = smgr ;
	}
	
	@Override
	public void update(Observable sender, Object dataobj) {
		/*
		 * this gets updated by the PageLoader, sub-class SeResultsDigester
		 */
		parent.out.setPrefix("[iTexx-Gui]");
		PageLoader pl ; // just for dev jumping
		parent.out.print(2, ".........SessionManager received an update as observer of "+sender.toString()+", receiving data of format "+dataobj.toString());
		
		if (dataobj instanceof SearchEngineResults){
			// if we get the whole package, fork into object ... 
			new ImporterHelper( parent, (SearchEngineResults)dataobj );
		}
		if (dataobj instanceof SearchEngineResultItem){
			SearchEngineResultItem ser = (SearchEngineResultItem)dataobj ;
			parent.seCompletedResultsItemsBuffer.add(ser) ;
		}
		
		
	}

	
}

class ImporterHelper{

	SessionManager parent;
	
	public ImporterHelper(SessionManager parent, SearchEngineResults serItem) {
		//
		this.parent = parent;
		go(serItem) ;
	}

	
	private void go(SearchEngineResults serItems){
		
		for (int i=0;i<serItems.size();i++){
			SearchEngineResultItem ser = serItems.get(i);
			parent.seCompletedResultsItemsBuffer.add(ser) ;
		}
		

	}
	
}